/*
 * MemoryManager.h
 * Manage retired memory according to the essay:
 * 		"Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects"
 *	 		(Maged M. Michael)
 * @author Hani shubin
 */
#ifndef MEMORYMANAGER_H_
#define MEMORYMANAGER_H_

#include "Node.h"
#include "list.h"

/**
 * This is the "R" from the essay.
 * After MAX_RETIRED_NODES nodes were retired,
 * the memoryManager tries to free memory
 */
#define MAX_RETIRED_NODES 10000

/**
 * remove all HP from a threadData td
 */
#define cleanHP(td) 	td.hp0 = td.hp1 = td.hp2 = td.hp3 = NULL;

/**
 * get threadData- avoid false-sharing
 */
#define GET_THREAD_DATA(tid) mm->threadsData[tid*NUM_BYTES_IN_CACHE_LINE]

/**
 * A list of Nodes
 */
typedef struct NodesList_t {
	Node *node;
	list_t npRetiredNode;
} RetiredNodes;

/**
 * This struct includes the data of a thread.
 * It saves the current HP's, and the list of the retired nodes.
 */
typedef struct ThreadData_t {
	Node* hp0;
	Node* hp1;
	Node* hp2;
	Node* hp3;
	int rSize;
	list_t retiredNodesHead;
} ThreadData;

/**
 * MemoryManager struct
 */
typedef struct MemoryManager_t {
	ThreadData *threadsData;
	int numThreads;
} MemoryManager;

/**
 * Get a MemoryManager (c'tor).
 * Input: numOfThreads that will use the MemoryManager.
 * Output: a new initialized MemoryManager.
 */
inline MemoryManager* getMemoryManager(unsigned int numOfThreads);

/**
 * Delete a MemoryManager (d'tor).
 * Input: a MemoryManager to be deleted.
 * Assumption: 	This function must be called after all threads have finished
 * 				running.
 */
inline void deleteMemoryManager(MemoryManager* mm);

/**
 * Retire a node. This node is added to the retired list and will be deleted
 * when the restricts for deleting would be fulfilled.
 */
inline void retireNode(MemoryManager* mm, Node* node, long tid);

#endif /* MEMORYMANAGER_H_ */
